/*******************************************************************************
 * Copyright (c) 2012, 2017 IBM Corp.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v1.0 which accompany this distribution.
 *
 * The Eclipse Public License is available at
 *   http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 *   http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *    Ian Craggs - initial contribution
 *******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTClient.h"
#include "cJSON.h"

#define ADDRESS "tcp://192.168.50.155:1883"
#define CLIENTID "ExampleClientSub"
#define TOPIC "down"
#define TOPIC1 "up"
#define QOS 1
#define TIMEOUT 10000L

volatile MQTTClient_deliveryToken deliveredtoken;

void delivered(void *context, MQTTClient_deliveryToken dt)
{
    printf("Message with token value %d delivery confirmed\n", dt);
    deliveredtoken = dt;
}

int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    // 尝试解析JSON消息
    cJSON *root = cJSON_Parse(message->payload);
    if (root)
    {
        printf("   JSON content:\n");

        cJSON *item = cJSON_GetObjectItem(root, "name");
        if (item && item->type == cJSON_String)
            printf("      name: %s\n", item->valuestring);

        item = cJSON_GetObjectItem(root, "age");
        if (item && item->type == cJSON_Number)
            printf("       age: %d\n", item->valueint);

        item = cJSON_GetObjectItem(root, "msg");
        if (item && item->type == cJSON_String)
            printf("       msg: %s\n", item->valuestring);

        cJSON_Delete(root);
    }
    else
    {
        printf("   Raw message: %.*s\n", message->payloadlen, (char *)message->payload);
    }

    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
}

void connlost(void *context, char *cause)
{
    printf("\nConnection lost\n");
    printf("     cause: %s\n", cause);
}

int main(int argc, char *argv[])
{
    // 创建JSON对象
    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "name", "xjaoming");
    cJSON_AddNumberToObject(root, "age", 16);
    cJSON_AddStringToObject(root, "msg", "hello world");

    MQTTClient client;
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    int rc;
    int ch;

    // 发布配置
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    MQTTClient_deliveryToken token;

    MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;

    MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered);

    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
        // 清理资源
        cJSON_Delete(root);
        // free(json_str);
        exit(EXIT_FAILURE);
    }

    printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
           "Press Q<Enter> to quit\n\n",
           TOPIC, CLIENTID, QOS);
    MQTTClient_subscribe(client, TOPIC, QOS);

    while (1)
    {
        // 读取用户输入 - 使用fgets处理空格
        char buf[1024] = {0};

        fgets(buf, sizeof(buf), stdin);
        buf[strcspn(buf, "\n")] = 0; // 移除换行符

        // 更新JSON中的msg字段
        cJSON_ReplaceItemInObject(root, "msg", cJSON_CreateString(buf));

        // 生成JSON字符串（稍后发布时使用）
        char *json_str = cJSON_Print(root);
        printf("Generated JSON: %s\n", json_str);
        // 发布JSON消息
        pubmsg.payload = json_str;
        pubmsg.payloadlen = (int)strlen(json_str);
        pubmsg.qos = QOS;
        pubmsg.retained = 0;

        MQTTClient_publishMessage(client, TOPIC1, &pubmsg, &token);
        printf("Publishing to topic: %s\n", TOPIC1);

        rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
        printf("Message with delivery token %d delivered\n", token);

        if (strcmp(buf, "q") == 0)
        {
            break;
        }

        // 现在可以安全释放JSON资源
        free(json_str);

        // do
        // {
        //     ch = getchar();
        // } while(ch != 'Q' && ch != 'q');
        // 检查退出命令
    }
    MQTTClient_unsubscribe(client, TOPIC);
    MQTTClient_disconnect(client, 10000);
    MQTTClient_destroy(&client);
    cJSON_Delete(root);

    return 0;
}
